package cn.wmw.xyy.service.impl;

import cn.wmw.xyy.domain.KillActivity;
import cn.wmw.xyy.domain.KillCourse;
import cn.wmw.xyy.exception.GlobalExceptionEnum;
import cn.wmw.xyy.mapper.KillActivityMapper;
import cn.wmw.xyy.service.IKillActivityService;
import cn.wmw.xyy.service.IKillCourseService;
import cn.wmw.xyy.utils.AssertUtil;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wmw
 * @since 2023-01-13
 */
@Slf4j
@Service
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {

    @Autowired
    private IKillCourseService killCourseService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Override
    @Transactional
    public void publish(Long killActivityId) {
        KillActivity killActivity = selectById(killActivityId);
        // 查询活动是否存在
        AssertUtil.isNotNull(killActivity, GlobalExceptionEnum.ERROR);
        // 发布状态是否为待发布
        AssertUtil.isTrue(KillActivity.WAIT_PUBLISH.equals(killActivity.getPublishStatus()), GlobalExceptionEnum.ERROR);
        // 活动的开始时间是否在当前时间之后
        Date now = new Date();
        Date beginTime = killActivity.getBeginTime();
        boolean isBefore = now.before(beginTime);
        AssertUtil.isTrue(isBefore, GlobalExceptionEnum.ERROR);
        // 该活动中是否存在课程
        List<KillCourse> killCourseList = killCourseService.selectByKillActivityId(killActivityId);
        AssertUtil.isTrue(killCourseList.size() > 0, GlobalExceptionEnum.ERROR);
        killCourseList.forEach(e->{
            // 设置每个课程的信号量
            Long activityId = e.getActivityId();
            Long killCourseId = e.getId();
            RSemaphore semaphore = redissonClient.getSemaphore(activityId + ":" + killCourseId);
            boolean isOk = semaphore.trySetPermits(e.getKillCount());
            if (isOk){
                // 将课程存入redis中
                redisTemplate.opsForHash().put("activity:" + activityId, killCourseId.toString(), e);
                // 修改状态发布状态
                e.setPublishStatus(KillCourse.ON_PUBLISH);
                e.setPublishTime(now);
            }else {
                log.info("秒杀课程信号量设置失败");
            }
        });
        killCourseService.updateBatchById(killCourseList);
        killActivity.setPublishStatus(KillActivity.ON_PUBLISH);
        killActivity.setPublishTime(now);
        updateById(killActivity);
    }

    @Override
    public boolean insert(KillActivity killActivity) {
        Date beginTime = killActivity.getBeginTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm");
        String timeStr = simpleDateFormat.format(beginTime);
        killActivity.setTimeStr(timeStr);
        killActivity.setPublishStatus(KillActivity.WAIT_PUBLISH);
        return super.insert(killActivity);
    }
}
